﻿

using UnityEngine;

public abstract class FM_BaseNote
{
    private readonly FM_NoteType type;
    public Color color;
    public bool tuplet = false;
    public int tupletSize = 0;
    public int voice = 0;
    public int displacedot = 0; // if 1, move dot up. If -1, move dot down.

    // On which staff do you want this Note? First (0) or Second (1). First staff uses FM_Score.FirstStaffKey, second one uses FM_Score.SecondStaffKey
    public int stave;

    public float paddingLeft;
    public float GetPaddingLeft() { return paddingLeft; }
    public void SetPaddingLeft(float p) { paddingLeft = p; }
    public abstract float WidthAccidental();
    public float paddingNote;
    public void SetPaddingNote(float p) { paddingNote = p; }
    public abstract float WidthNoteNoStem();
    public abstract float WidthNote();
    public float paddingDot;
    public void SetPaddingDot(float p) { paddingDot = p; }
    public abstract float WidthDot();
    public virtual float Width() { return paddingLeft + WidthAccidental() + paddingNote + WidthNote() + paddingDot + WidthDot(); }
    // float WidthNoDot() { return paddingLeft + WidthAccidental() + paddingNote + WidthNote(); }
    // float WidthNoStem(){ return paddingLeft + WidthAccidental() + paddingNote + WidthNoteNoStem() + paddingDot + WidthDot(); }
    public virtual float WidthNoDotNoStem() { return paddingLeft + WidthAccidental() + paddingNote + WidthNoteNoStem(); }

    public bool visible;
    public bool blurred;
    public FM_ScoreBase score;
    public float StartX;
    public float GetStartX()
    {
        return StartX;
    }
    public float StartY1, StartY2;
    public int line;
    //[FM_NoteValue]
    public int note;
    public int octave;
    //[FM_Accidental]
    public int accidental;
    //[FM_DurationValue]
    public FM_DurationValue duration;
    public bool stem;
    public bool stem_up;

    protected FM_BaseNote(/*[FM_NoteType]*/ FM_NoteType type, FM_ScoreBase score)
    {
        this.type = type;
        paddingDot = 0f;
        paddingNote = 0f;
        if (score.score != null) SetPaddingLeft(FM_Const.dpTOpx( 4));
        stave = 0;
        this.score = score;
        this.visible = true;
        this.blurred = false;
        this.line = 1;
        if (score.score != null) color = score.score.GetColor();
        note = FM_NoteValue.DO;
        octave = 0;
        accidental = FM_Accidental.None;
        stem = false;
        stem_up = true;
    }

    public void RemoveAccidental()
    {
        accidental = FM_Accidental.None;
    }
    public virtual void SetDrawParameters(float StartX, float StartY1, float StartY2)
    {
        this.StartX = StartX;
        this.StartY1 = StartY1;
        this.StartY2 = StartY2;
    }
    public virtual void DrawNote(ScoreCanvas canvas)
    {
        if (score.score == null) return;
        //score.score.Font.Color = color;
        if (score.score.GetShowBoundingBoxes() == FM_BoundingBoxType.None) return;

        if ((score.score.GetShowBoundingBoxes() == FM_BoundingBoxType.Chord && this is FM_Chord) ||
            (score.score.GetShowBoundingBoxes() == FM_BoundingBoxType.Note && !(this is FM_Chord)))
        {
            Paint p = new Paint();
            p.Color = new Color(255, 255, 0, 0);
            if (this is FM_Chord) p.Color = new Color(255, 255, 0, 255);
            float bx = Left();
            float tx = Right();
            float by = Bottom();
            float ty = Top();
            canvas.DrawLine(bx, by, bx, ty);
            canvas.DrawLine(bx, ty, tx, ty);
            canvas.DrawLine(tx, ty, tx, by);
            canvas.DrawLine(tx, by, bx, by);
        }
    }
    public abstract float GetDisplacement();
    public abstract string AsString();
    public abstract float Left();
    public abstract float Bottom();
    public abstract float Right();
    public abstract float Top();

    public Color GetColor()
    {
        return color;
    }
    public virtual void SetColor(Color color)
    {
        this.color = color;
    }
    public bool IsVisible()
    {
        return visible;
    }
    public bool IsBlurred()
    {
        return blurred;
    }
    public virtual void SetBlurred(bool blurred)
    {
        this.blurred = blurred;
    }
    public virtual void SetVisible(bool visible)
    {
        this.visible = visible;
    }
    public int GetAccidental()
    {
        return accidental;
    }

    public FM_NoteType GetNoteType()
    {
        return type;
    }
    public int GetStave() { return stave; }

    public FM_DurationValue GetDuration()
    {
        return duration;
    }
}
